#pragma once

#include "SehnsuchtPrecompiled.hxx"
#include "SehnsuchtTimerView.hxx"

namespace Sehnsucht
{
	class_decl BasicTimer : public_shared_access BasicTimerView
	{
	owned_access:

		typedef void(BasicTimer::*UpdateDelegate)();
		UpdateDelegate	m_UpdateCallback;

		REIGN_FORCEINLINING Void UpdateNonfixedStepImpl()
		{
			auto const High = _To_single(m_CurrentTicks64 - m_LastTicks64);
			auto const Low = _To_single m_TicksPerSecond64;
			m_fDelta = (High / Low);
		}

		REIGN_FORCEINLINING Void UpdateFixedStepImpl()
		{
			m_fDelta = m_fFixedDelta;
		}

	public_shared_access:

		void SetFixedTimeStep(Float32Const fStep);
		DeclGetPropOnly(BasicTimerViewConstPtrConst, View); // Gets timer view
		REIGN_FORCEINLINING DeclConstTypedGetterFor(BasicTimerViewConstPtrConst, View) { return this; } // Gets timer view

		BasicTimer();
		void Reset();

		REIGN_HINTINLINING Void Update()
		{
			m_LastTicks64 = m_CurrentTicks64;
			QueryPerformanceCounter(_Outptr_opt_ _To_large_int_ptr &m_CurrentTicks64);
			(this->*m_UpdateCallback)();

			auto const High = _To_single(m_CurrentTicks64 - m_OneSecondTicks64);
			auto const Low = _To_single m_TicksPerSecond64;
			auto const Value = (High / Low);

			if (Value < 1.0f) m_iFrameCount++;
			else
			{
				m_OneSecondTicks64 = m_CurrentTicks64;
				m_iFramesPerSecond = m_iFrameCount;
				m_iFrameCount = 0;

				// Not useful for now
				// Uncomment to evaluate max fps
				//if ( m_iFramesPerSecond > m_iMaxFramesPerSecond )
				//m_iMaxFramesPerSecond = m_iFramesPerSecond;
			}
		}
	};
};